# -*- coding: UTF-8 -*-
import sys
import urllib.request
from importlib import reload
from bs4 import BeautifulSoup
import csv
import time

# 用的python版本是 Python 3.8.8
reload(sys)

# 定义一个头部，避免反爬
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36',
    'Referer': 'https://movie.douban.com/',
    'Connection': 'keep-alive'
}

# 存放洗衣机参数详情页面的列表
link_list = []
# 洗衣机的链接，过滤条件是 半自动与全自动
base_url = 'https://detail.zol.com.cn/washer_advSearch/subcate372_1_s8375-s8376_1_1__'
# 控制需要爬取的页面数，不包括当前的数字页；调试期间少爬取点，避免引起反爬
# page_start_num = 146 + 18
page_start_num = 1
page_end_num = 223
for i in range(page_start_num, page_end_num):
    # 控制页数的关键在于最后一个数字
    url = base_url + str(i) + '.html#showc'
    print('每一页的链接' + url)

    # 给url加头部
    _url = urllib.request.Request(url, headers=headers)
    response = urllib.request.urlopen(_url)
    page = response.read()
    # 使用beautiful soup解析html页面，page是字符串
    soup = BeautifulSoup(page, 'html.parser')
    ul = soup.find('ul', class_='result_list')
    if ul != None:
        temp = ul.find_all('a', string='更多参数>>')
        if temp != None:
            for link in temp:
                link_list.append('http://detail.zol.com.cn' + link['href'])  # 把每个洗衣机的参数详情页存进数组
    # print('参数详情页的数量：' + len(link_list).__str__())

# 保存数据进文件,为csv格式，可以用excel打开
# 因为一次过获取全部数据有被反爬的风险，所以获取一条就保存一条到excel里
washer_csv_path = 'washer.csv'
file = open(washer_csv_path, 'a+', encoding='gbk', newline='')
csv_writer = csv.writer(file)
csv_writer.writerow([f'洗衣机名称', '能效等级', '耗电量/额定功率'])
file.close()

# 把所有数据保存在列表中
res_list = []
# 表示当前是第几条数据
step = (page_start_num - 1) * 30 + 1
for url in link_list:  # 遍历每一个手机的参数详情页
    try:
        # 为了能够看到进度，所以把每一个详情页的链接打印出来
        print('第{}个详情页的链接：{}'.format(step, url))
        # 保存单条结果的 字典
        result = {}
        # 访问网页，给url加头部
        _url = urllib.request.Request(url, headers=headers)
        response = urllib.request.urlopen(_url)
        # 获取响应的页面
        page = response.read()
        # 使用beautiful soup解析html页面，page是字符串
        soup = BeautifulSoup(page, 'html.parser')
        # 去掉多余的br，br有可能会导致BeautifulSoup解析出错
        for linebreak in soup.find_all('br'):
            linebreak.extract()

        # 使用Beautiful Soup提供的方法定位我们想要得到的参数信息
        # 获取洗衣机的名称
        try:
            washer_name = soup.find('h1', class_='product-model__name').string
            if washer_name != None:  # 如果洗衣机名称存在
                result['washer_name'] = washer_name.split('参数')[0]
                # print('洗衣机名称：' + washer_name.split('参数')[0])
        except Exception as e:
            result['washer_name'] = '暂无数据'

        # 获取洗衣机能效
        try:
            list = soup.find('ul', class_='product-param-item').find_all('li')
            for li in list:
                ps = li.find_all('p')
                for p in ps:
                    spans = p.find_all('span')
                    span_name = spans[0].string
                    # print(spans[0].string)
                    if span_name == '能效等级：':  # 如果 能效等级 存在
                        result['Energy_efficiency_level'] = spans[0].parent.text.split('：')[1]
                        # print('能效等级:' + spans[0].parent.text.split('：')[1])
        except Exception as e:
            result['Energy_efficiency_level'] = '暂无数据'

        # 获取洗衣机的 耗电量 或者 额定功率
        try:
            spans = soup.find_all('span')
            for span in spans:
                if span.text == '耗电量':
                    tr = span.parent.parent
                    td = tr.find('td')
                    td_span = td.find('span')
                    result['power'] = td_span.text.split('千瓦')[0]
                    # print('耗电量:' + td_span.text)

                if span.text == '额定功率':
                    tr = span.parent.parent
                    td = tr.find('td')
                    td_span = td.find('span')
                    result['power'] = td_span.text.split('千瓦')[0]
                    # print('耗电量:' + td_span.text)
        except Exception as e:
            result['power'] = '暂无数据'

        if 'power' not in result.keys():  # 如果 耗电量/额定功率 不存在，则赋值为‘无数据’
            result['power'] = '暂无数据'

        try:
            # 保存数据到excel里
            with open(washer_csv_path, 'a+', encoding='gbk', newline='') as f_csv:
                csv_writer = csv.writer(f_csv)
                csv_writer.writerow([result['washer_name'], result['Energy_efficiency_level'], result['power']])
        except Exception as e:
            pass

        # 每爬一个链接，暂停3秒，模拟真实用户行为，避免反爬
        time.sleep(3)
        step = step + 1
    except Exception as e:
        print('出错的链接：{}'.format(url))

print('文件生成完毕！')

# 打印总的数据量
# print('洗衣机总数：'.format(len(res_list)))

# 打印抓取的数据，调试使用，非调试不打开
# for res in res_list:
#     print('洗衣机名称:{},能效等级:{},耗电量/额定功率:{}'.format(res['washer_name'], res['Energy_efficiency_level'],
#                                                                 res['power']))
